import multer from 'multer';
import path from 'path';
import fs from 'fs';
import { createError } from './errorHandler';
import { logger } from '../utils/logger';
import { validateFileType, getFileTypeConfig, DEFAULT_FILE_SIZE_LIMIT } from '../config/fileTypes';
import { getStoragePath, ensureDirectoryExists, generateUniqueFilename, initializeStorageDirectories } from '../config/storage';

// 初始化存储目录
initializeStorageDirectories();

// 配置存储
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    try {
      // 获取文件类型配置
      const fileConfig = getFileTypeConfig(file.mimetype);
      const category = fileConfig?.category || 'unknown';
      
      // 获取存储路径
      const storagePath = getStoragePath(category);
      
      // 确保目录存在
      ensureDirectoryExists(storagePath);
      
      logger.info('文件存储路径', {
        filename: file.originalname,
        category,
        storagePath
      });
      
      cb(null, storagePath);
    } catch (error: any) {
      logger.error('确定存储路径失败', { error: error.message });
      cb(error, 'uploads/');
    }
  },
  filename: (req, file, cb) => {
    try {
      const userId = (req as any).user?.id;
      const filename = generateUniqueFilename(file.originalname, userId);
      
      logger.info('生成文件名', {
        originalname: file.originalname,
        filename,
        userId
      });
      
      cb(null, filename);
    } catch (error: any) {
      logger.error('生成文件名失败', { error: error.message });
      const fallbackName = Date.now() + '-' + Math.round(Math.random() * 1E9) + path.extname(file.originalname);
      cb(null, fallbackName);
    }
  }
});

// 文件过滤器
const fileFilter = (req: any, file: Express.Multer.File, cb: multer.FileFilterCallback) => {
  try {
    // 获取文件扩展名
    const ext = path.extname(file.originalname).toLowerCase();
    
    // 记录文件上传尝试
    logger.info('文件上传验证', {
      originalname: file.originalname,
      mimetype: file.mimetype,
      extension: ext,
      size: file.size
    });
    
    // 验证文件名
    if (!file.originalname || file.originalname.length === 0) {
      logger.warn('文件上传失败: 文件名为空');
      cb(createError('文件名不能为空', 400));
      return;
    }
    
    // 验证文件扩展名存在
    if (!ext || ext.length <= 1) {
      logger.warn('文件上传失败: 缺少文件扩展名', { filename: file.originalname });
      cb(createError('文件必须包含有效的扩展名', 400));
      return;
    }
    
    // 验证文件类型
    const validation = validateFileType(file.mimetype, ext);
    if (!validation.isValid) {
      logger.warn('文件上传失败: 文件类型验证失败', {
        filename: file.originalname,
        mimetype: file.mimetype,
        extension: ext,
        reason: validation.message
      });
      cb(createError(validation.message || '不支持的文件类型', 400));
      return;
    }
    
    // 获取文件类型配置以检查特定大小限制
    const fileConfig = getFileTypeConfig(file.mimetype);
    if (fileConfig && fileConfig.maxSize && req.headers['content-length']) {
      const fileSize = parseInt(req.headers['content-length']);
      if (fileSize > fileConfig.maxSize) {
        const maxSizeMB = Math.round(fileConfig.maxSize / 1024 / 1024);
        logger.warn('文件上传失败: 文件大小超限', {
          filename: file.originalname,
          fileSize,
          maxSize: fileConfig.maxSize,
          category: fileConfig.category
        });
        cb(createError(`${fileConfig.category} 类型文件大小不能超过 ${maxSizeMB}MB`, 400));
        return;
      }
    }
    
    logger.info('文件类型验证通过', {
      filename: file.originalname,
      mimetype: file.mimetype,
      extension: ext
    });
    
    cb(null, true);
  } catch (error: any) {
    logger.error('文件过滤器错误', { error: error.message, stack: error.stack });
    cb(createError('文件验证失败', 500));
  }
};

// 创建上传中间件
export const uploadMiddleware = multer({
  storage,
  fileFilter,
  limits: {
    fileSize: 100 * 1024 * 1024, // 100MB 最大限制（特定类型会在fileFilter中进一步限制）
    files: 10, // 最多10个文件
    fieldSize: 10 * 1024 * 1024, // 单个字段最大10MB
    headerPairs: 200 // 限制header数量防止攻击
  },
});

// 处理Multer错误的中间件
export const handleMulterError = (error: any, req: any, res: any, next: any) => {
  if (error instanceof multer.MulterError) {
    logger.warn('Multer错误', { 
      code: error.code, 
      message: error.message,
      field: error.field 
    });
    
    switch (error.code) {
      case 'LIMIT_FILE_SIZE':
        res.status(400).json({
          success: false,
          message: '文件大小超过限制',
          code: 'FILE_TOO_LARGE'
        });
        break;
      case 'LIMIT_FILE_COUNT':
        res.status(400).json({
          success: false,
          message: '文件数量超过限制',
          code: 'TOO_MANY_FILES'
        });
        break;
      case 'LIMIT_UNEXPECTED_FILE':
        res.status(400).json({
          success: false,
          message: '不允许的文件字段',
          code: 'UNEXPECTED_FIELD'
        });
        break;
      default:
        res.status(400).json({
          success: false,
          message: '文件上传失败',
          code: 'UPLOAD_ERROR'
        });
    }
  } else if (error) {
    next(error);
  } else {
    next();
  }
};